package com.softer.wxzj.controller;

import com.softer.wxzj.common.entity.CommonResult;
import com.softer.wxzj.common.enums.ShiroMessageEnum;
import com.softer.wxzj.common.enums.ShiroResultEnum;
import com.softer.wxzj.common.util.CaptchaUtil;
import com.softer.wxzj.entity.SysUser;
import com.softer.wxzj.service.LoginService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.pam.UnsupportedTokenException;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;

/**
 * LoginController class
 * @author zcz
 * @date 2019/1/16
 */
@RestController
@Slf4j
public class LoginController {
    @Autowired
    private LoginService loginService;

    public static final String KEY_CAPTCHA = "KEY_CAPTCHA";
    /**
     * 退出
     * @return
     */
    @GetMapping("/logout")
    public CommonResult logout() {
        Subject subject = SecurityUtils.getSubject();
        if (subject != null) {
            subject.logout();
        }
        return new CommonResult(ShiroResultEnum.SUCCESS.getCode(), ShiroMessageEnum.SHIRO_AUTHC_LOGOUT_MESSAGE.getMsg());
    }

    /**
     * 登录
     * @param userName
     * @param passWord
     * @param rememberMe
     * @return
     */
    @PostMapping("/login")
    public CommonResult login(@RequestParam("userName") String userName,
                              @RequestParam("passWord") String passWord,
                              @RequestParam("captcha") String captcha,
                              boolean rememberMe) {
        System.out.println("rememberMe:"+rememberMe);
        log.info("登录开始，用户名："+userName);
        //session中的验证码
        String sessionCaptcha = (String) SecurityUtils.getSubject().getSession().getAttribute(KEY_CAPTCHA);
        if (StringUtils.isBlank(captcha) || !captcha.equalsIgnoreCase(sessionCaptcha)) {
            return new CommonResult(ShiroResultEnum.FAIL.getCode(), "验证码不正确！");
        }
        log.info("captcha："+userName);
        UsernamePasswordToken token = new UsernamePasswordToken(userName, passWord,rememberMe);
        Subject subject = SecurityUtils.getSubject();
        log.info("登录结束！");
        return exceptionMessage(subject,token);
    }

    public CommonResult exceptionMessage(Subject subject, UsernamePasswordToken token){
        try{
            subject.login(token);
            SysUser user = (SysUser) subject.getPrincipal();
            loginService.updateLastLoginTime(user.getUserName());
            return new CommonResult(ShiroResultEnum.SUCCESS.getCode(), ShiroMessageEnum.SHIRO_AUTHC_LOGIN_MESSAGE.getMsg());
        }catch (UnknownAccountException unknownAccountException){
            return new CommonResult(ShiroResultEnum.FAIL.getCode(), ShiroMessageEnum.SHIRO_AUTHC_UNKNOWNACCOUNTEXCEPTION_MESSAGE.getMsg());
        }catch (IncorrectCredentialsException incorrectCredentialsException){
            return new CommonResult(ShiroResultEnum.FAIL.getCode(), ShiroMessageEnum.SHIRO_AUTHC_INCORRECTCREDENTIALSEXCEPTION_MESSAGE.getMsg());
        }catch (LockedAccountException lockedAccountException){
            return new CommonResult(ShiroResultEnum.FAIL.getCode(), ShiroMessageEnum.SHIRO_AUTHC_LOCKEDACCOUNTEXCEPTION_MESSAGE.getMsg());
        }catch (DisabledAccountException disabledAccountException){
            return new CommonResult(ShiroResultEnum.FAIL.getCode(), ShiroMessageEnum.SHIRO_AUTHC_DISABLEDACCOUNTEXCEPTION_MESSAGE.getMsg());
        }catch (ExcessiveAttemptsException excessiveAttemptsException){
            return new CommonResult(ShiroResultEnum.FAIL.getCode(), ShiroMessageEnum.SHIRO_AUTHC_EXCESSIVEATTEMPTSEXCEPTION_MESSAGE.getMsg());
        }catch (ConcurrentAccessException concurrentAccessException){
            return new CommonResult(ShiroResultEnum.FAIL.getCode(), ShiroMessageEnum.SHIRO_AUTHC_CONCURRENTACCESSEXCEPTION_MESSAGE.getMsg());
        }catch (AccountException accountException){
            return new CommonResult(ShiroResultEnum.FAIL.getCode(), ShiroMessageEnum.SHIRO_AUTHC_ACCOUNTEXCEPTION_MESSAGE.getMsg());
        }catch (UnsupportedTokenException unsupportedTokenException){
            return new CommonResult(ShiroResultEnum.FAIL.getCode(), ShiroMessageEnum.SHIRO_AUTHC_UNSUPPORTEDTOKENEXCEPTION_MESSAGE.getMsg());
        }catch (CredentialsException credentialsException){
            return new CommonResult(ShiroResultEnum.FAIL.getCode(), ShiroMessageEnum.SHIRO_AUTHC_CREDENTIALSEXCEPTION_MESSAGE.getMsg());
        }catch (AuthenticationException authenticationException){
            return new CommonResult(ShiroResultEnum.FAIL.getCode(), ShiroMessageEnum.SHIRO_AUTHC_AUTHENTICATIONEXCEPTION_MESSAGE.getMsg());
        }
    }

    /**
     * 获取验证码
     * @param request
     * @param response
     */
    @RequestMapping("/Captcha.jpg")
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response){
        // 设置相应类型,告诉浏览器输出的内容为图片
        response.setContentType("image/jpeg");
        // 不缓存此内容
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expire", 0);
        try {
            HttpSession session = request.getSession();
            CaptchaUtil tool = new CaptchaUtil();
            StringBuffer code = new StringBuffer();
            BufferedImage image = tool.genRandomCodeImage(code);
            session.removeAttribute(KEY_CAPTCHA);
            session.setAttribute(KEY_CAPTCHA, code.toString());
            // 将内存中的图片通过流动形式输出到客户端
            ImageIO.write(image, "JPEG", response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

}
